import { PrismaClient } from "@prisma/client";
import { CreateGroupInput } from "../dto/group.dto";
import { HttpError } from "../utils/httpError";
import { ErrorCode } from "../constants/errorCode";
import { NotificationType } from "../constants/notificationType";
import { sendNoticeMessage } from "./message.service";

const prisma = new PrismaClient();

export const createGroup = async (userId: number, input: CreateGroupInput) => {
  const group = await prisma.groups.create({
    data: {
      name: input.name,
      avatar: input.avatar,
      owner_id: userId,
    },
  });

  const allMembers = Array.from(new Set([userId, ...(input.member_ids || [])]));

  await prisma.group_members.createMany({
    data: allMembers.map((uid) => ({
      group_id: group.id,
      user_id: uid,
      role: uid === userId ? 2 : 0, // 👈 群主为 2，其他为普通成员
    })),
    skipDuplicates: true,
  });

  return group;
};

export const getUserGroups = async (user_id: number) => {
  // 查询用户所在的群，并 include 成员列表
  const groups = await prisma.groups.findMany({
    where: {
      group_members: {
        some: {
          user_id
        }
      }
    },
    include: {
      group_members: {
        include: {
          users: {
            select: {
              id: true,
              username: true,
              avatar: true
            }
          }
        }
      }
    }
  });

  // 映射结果为前端格式
  return groups.map(group => ({
    id: group.id,
    name: group.name,
    owner_id: group.owner_id,
    created_at: group.created_at,
    members: group.group_members.map(m => ({
      id: m.users.id,
      username: m.users.username,
      avatar: m.users.avatar,
      role: m.role
    }))
  }));
};


/**
 * @description 获取群成员
 * @param groupId 群组id
 * @returns 群成员
 */
export const getGroupMembers = async (groupId: number) => {
  const members = await prisma.group_members.findMany({
    where: { group_id: groupId },
    include: {
      users: true,
    },
  });

  return members.map((m) => ({
    id: m.user_id.toString(),
    username: m.users.username,
    avatar: m.users.avatar,
    role: m.role,
    joined_at: m.joined_at,
  }));
};

/**
 * @description 邀请用户加入群组
 * @param groupId 群组id
 * @param inviterId 邀请者id
 * @param targetUserId 被邀请者id
 */
export const inviteToGroup = async (
  groupId: number,
  inviterId: number,
  targetUserIds: number[]
) => {
  const uniqueIds = Array.from(new Set(targetUserIds));

  const existing = await prisma.group_members.findMany({
    where: {
      group_id: groupId,
      user_id: { in: uniqueIds },
    },
    select: { user_id: true },
  });

  const alreadyInGroupIds = new Set(existing.map((e) => Number(e.user_id)));
  const toAdd = uniqueIds.filter((uid) => !alreadyInGroupIds.has(uid));
  if (toAdd.length === 0) {
    throw new HttpError(ErrorCode.CONFLICT, 409, "所有用户已在群中");
  }
  //ToDo 只有群主或已有成员才可邀请（可扩展）
  const res = await prisma.group_members.createMany({
    data: toAdd.map((uid) => ({
      group_id: groupId,
      user_id: uid,
      role: 0,
    })),
    skipDuplicates: true,
  });
  if (res.count === 0) {
    throw new HttpError(ErrorCode.CONFLICT, 409, "邀请失败");
  } else {
    // 发送通知
    const group = await prisma.groups.findUnique({ where: { id: groupId } });
    const inviteUser = await prisma.users.findUnique({
      where: { id: inviterId },
    });
    if (group) {
      await prisma.notifications.createMany({
        data: targetUserIds.map((uid) => ({
          user_id: uid,
          type: NotificationType.GROUP_INVITE,
          content: `你被${inviteUser?.username}邀请加入群组「${group.name}」`,
          status: 0,
        })),
      });
      targetUserIds.forEach((uid) => {
        const message = {
          type: NotificationType.GROUP_INVITE,
          content: `你被${inviteUser?.username}邀请加入群组「${group.name}」`,
        };
        // 发送通知
        sendNoticeMessage(uid, JSON.stringify(message));
      });
    }
  }
};

export const leaveGroup = async (
  groupId: number,
  targetUserIds: number[],
  operatorId: number
) => {
  const group = await prisma.groups.findUnique({ where: { id: groupId } });

  if (!group) {
    throw new HttpError(ErrorCode.USER_NOT_FOUND, 404, "群组不存在");
  }

  // 群主不能退出群（保护）
  if (group.owner_id && targetUserIds.includes(Number(group.owner_id))) {
    throw new HttpError(ErrorCode.FORBIDDEN, 403, "群主不能退出群");
  }

  // 如果不是自己退出，限制只能操作自己或自己是群主
  const onlySelf =
    targetUserIds.length === 1 && targetUserIds[0] === operatorId;
  const isOwner = Number(group.owner_id) === operatorId;

  if (!onlySelf && !isOwner) {
    throw new HttpError(ErrorCode.FORBIDDEN, 403, "你无权移除他人");
  }

  const result = await prisma.group_members.deleteMany({
    where: {
      group_id: groupId,
      user_id: { in: targetUserIds },
    },
  });

  if (result.count === 0) {
    throw new HttpError(ErrorCode.FORBIDDEN, 403, "你或目标成员不在群中");
  }
};

/**
 * @description 解散群组
 * @param groupId 群组id
 * @param userId
 */
export const deleteGroup = async (groupId: number, userId: number) => {
  const group = await prisma.groups.findUnique({ where: { id: groupId } });
  if (!group || Number(group.owner_id) !== userId) {
    throw new HttpError(ErrorCode.FORBIDDEN, 403, "只有群主可以解散群");
  }
  await prisma.group_members.deleteMany({ where: { group_id: groupId } });
  await prisma.groups.delete({ where: { id: groupId } });
};
